#include "mat_gameover_gemcleareffect.h"
#include "mat_game.h"
#include "mat_gem.h"
#include "mat_gamerule.h"

#include "audio/audio.h"
#include "part2d/part2d.h"
#include "util/common_macros.h"

namespace endfx
{
	static const float LAUNCH_VELOCITY = 0.5f;
	static const float GRAVITY = 0.75f;
	static const float ROTATE_RATE = 360.0f;
};

MATClearGem::~MATClearGem()
{
	Clear();
}


void	MATClearGem::Init(bool bWinGame)
{
	const float invRandMax = 1.0f / float(RAND_MAX);

	//WIZDwarvenBlock* pBlock = NULL;
	//std::vector<well::BaseBlock*> Set;
	ENDFX_NODE Data;

	if(m_bInit)
		Clear();

	//GetAllBlocks(Set);

	MATGem* pTempGem = NULL;

	for(int y = 0; y< MATGameRule::Instance().GetBoardCountY(); y++)
	{
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			pTempGem = MATLogicBoard::Instance().GetContentAt(y,x);
			if(pTempGem && pTempGem->m_Type > 0)
			{
				Data.m_pSprite =  MATGame::GetSpriteByGem(pTempGem);				
				Data.Pos = MATGame::GetBoardPos(y,x);
				Data.Speed = Data.Pos - math::Vec2(0.5f,0.5f);
				Data.Speed.Normalize();

				if (bWinGame)
				{
					math::Vec2 Dist = Data.Pos - math::Vec2(0.5f, 0.5f);
					float factor = 1.0f - Dist.Magnitude();
					Data.Speed *= endfx::LAUNCH_VELOCITY * factor;
				}
				else
					Data.Speed *= endfx::LAUNCH_VELOCITY * (0.75f + (0.5f * float(rand()) * invRandMax));


				Data.Rotate = 360.0f * float(rand()) * invRandMax;
				Data.RotSpeed = endfx::ROTATE_RATE * (0.5f + (float(rand()) * invRandMax));
				if (rand() % 2)
					Data.RotSpeed = -Data.RotSpeed;

				if(Data.m_pSprite)
					m_Blocks.push_back(Data);
			}
		}
	}

	if((int)m_Blocks.size() > 0)
		m_bInit = true;
	m_bWinFX = bWinGame;	
}

void	MATClearGem::Clear()
{
	m_Blocks.clear();
	m_bInit = false;
}

bool	MATClearGem::Tick(float dt)
{
	if (!m_bInit) 
		return true;

	for (int i = (int)(m_Blocks.size() - 1); i >= 0; i--)
	{
		if (!m_bWinFX)
			m_Blocks[i].Speed.y += dt * endfx::GRAVITY;

		m_Blocks[i].Pos += dt * m_Blocks[i].Speed;

		if (m_Blocks[i].Pos.y > 1.0f)
		{
			m_Blocks.erase(m_Blocks.begin() + i);
			continue;
		}
		else if (m_bWinFX)
		{
			if ((m_Blocks[i].Pos.x < MATGame::GetGemSize().x)  ||
				(m_Blocks[i].Pos.x > 1.0f) ||
				(m_Blocks[i].Pos.y < -MATGame::GetGemSize().y))
			{
				m_Blocks.erase(m_Blocks.begin() + i);
				continue;
			}
		}
		else
		{
			if (m_Blocks[i].Pos.x < 0.0f)
			{
				m_Blocks[i].Pos.x = 0.0f;
				m_Blocks[i].Speed.x = -0.75f * m_Blocks[i].Speed.x;
			}
			else if (m_Blocks[i].Pos.x > 1.0f)
			{
				m_Blocks[i].Pos.x = 1.0f;
				m_Blocks[i].Speed.x = -0.75f * m_Blocks[i].Speed.x;
			}
		}

		m_Blocks[i].Rotate += dt * m_Blocks[i].RotSpeed;
		if (fabs(m_Blocks[i].Rotate) > 360.0f)
			m_Blocks[i].Rotate = fmod(m_Blocks[i].Rotate, 360.0f);

		
	}

	return m_Blocks.empty();
}

void	MATClearGem::Render()
{
	if (!m_bInit) return;
	ui::UISprite* pSprite = NULL;
	for (int i = (int)(m_Blocks.size() - 1); i >= 0; i--)
	{
		m_Blocks[i].m_pSprite->Setup( m_Blocks[i].Pos + (0.5f * MATGame::GetGemSize()),
												MATGame::GetGemSize(),
												m_Blocks[i].Rotate);
		m_Blocks[i].m_pSprite->RenderRotated();
		
		
	}
}
